﻿package dut.ir.lxb.weibo.spider;


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;

import org.apache.log4j.Logger;

import dut.ir.lxb.weibo.bean.UserBean;
import dut.ir.lxb.weibo.bean.UserWeiboAction;
import dut.ir.lxb.weibo.bean.WeiboBean;
import dut.ir.lxb.weibo.db.UserInfoDao;
import dut.ir.lxb.weibo.db.UserWeiboActionDao;
import dut.ir.lxb.weibo.db.WeiboInfoDao;
import dut.ir.lxb.weibo.main.UserWeiboDownloadTest;
import dut.ir.lxb.weibo.util.ActionType;
import dut.ir.lxb.weibo.util.SpiderConfig;
import dut.ir.lxb.weibo.util.SpiderUtility;

public class UserWeiboDownloadThread implements Runnable
{
	
	protected Queue<WeiboDownloader> downloaderList; 
	
	protected Queue<String> downloadQueue;
	
	protected Set<String> downloadedUids = new HashSet<String>();
	
	protected static Logger logger;
	
	protected static BufferedWriter downloadedUidWriter;
	
	
	static
	{
		logger = UserWeiboDownloadTest.logger;
		try
		{
			downloadedUidWriter = new BufferedWriter(new FileWriter("./config/downloadeduids.txt", true));
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public UserWeiboDownloadThread()
	{
		downloaderList = DownloadThread.loadWeiboDownloaderList();
		downloadQueue = new LinkedList<String>();
		downloadedUids = new HashSet<String>();
		init();
	}
	
	
	
	public void loadDownloadedUids()
	{
		try
		{
			BufferedReader br = new BufferedReader(new FileReader("./config/downloadeduids.txt"));
			String line = null;
			while((line = br.readLine()) != null)
			{
				if(!line.equals("") && line.length() == 10)
					downloadedUids.add(line.trim());
			}
			br.close();
			
		} 
		catch (FileNotFoundException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	
	/**
	 * 初始化
	 */
	public void init()
	{
		if(downloadQueue == null)
			downloadQueue = new LinkedList<String>();
		
		//loadDownloadedUids();
		String uidFile = SpiderConfig.getUidsFile();
		try
		{
			BufferedReader br = new BufferedReader(new FileReader(uidFile));
			String line = null;
			while((line = br.readLine()) != null)
			{
				String uid = line.trim();
				if(uid.length() < 2)
					continue;
				if(!downloadQueue.contains(uid) && !downloadedUids.contains(uid))
					downloadQueue.add(uid);
			}
			br.close();
			//从下载队列中找出上一次下载的UID
			String lastUid = SpiderUtility.getLastDownloadUser();
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String dateValue = df.format(new Date());
			String info = String.format("[%s]上一次下载到用户[%s]", dateValue, lastUid);
			logger.info(info);
			
			//while(!lastUid.equals(downloadQueue.peek()))
			//{
			//	downloadQueue.poll();
			//}
			//downloadQueue.clear();
			//downloadQueue.add(SpiderConfig.getRootUid());
		} catch (FileNotFoundException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	

	/* (non-Javadoc)
	 * @see java.lang.Runnable#run()
	 */
	@Override
	public void run()
	{
		WeiboDownloader wd = downloaderList.poll();
		wd.init();
		wd.setAccessDataBase(true);
		if(!wd.checkAccount())
			wd = getUsefulDownloader(downloaderList);

		while(true)
		{
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String dateValue = df.format(new Date());
			
			if(!wd.isLogin())
				wd = getUsefulDownloader(downloaderList);
			
			if(!wd.isLogin() && (downloaderList == null || downloaderList.size() == 0))
			{
				System.out.println("无可用微博帐号，退出程序");
				return ;
				//break;
			}
			String uid = downloadQueue.poll();
			
			UserInfoDao userDao = UserInfoDao.getInstance();
			WeiboInfoDao weiboDao = WeiboInfoDao.getInstance();
			UserWeiboActionDao actionDao = UserWeiboActionDao.getInstance();
			
			UserBean ub = null;
			//若下载用户页面被封号，则切换帐号重新登录
			try
			{
				ub = wd.downloadUserInfo(uid);
			
				//if(ub == null)
					//continue;
				userDao.insertUser(ub);
				
				String userInfo = String.format("[%s]正在下载 %s[%s] 的微博", dateValue, ub.getNickName(), ub.getUid());
				logger.info(userInfo);
				//System.out.println(userInfo);
				wd.downloadAUserWeibo(ub);
				List<WeiboBean> weiboList = weiboDao.getWeiboListByUid(ub.getUid(), false);
//				downloadedUidWriter.write(uid);
//				downloadedUidWriter.newLine();
//				downloadedUidWriter.flush();
//				weiboDao.insertWeiboList(weiboList);
				int count = 0;
				for(WeiboBean weibo : weiboList)
				{
					count++;
//					if(true) break;
					if(weibo.getLikeNum() > SpiderConfig.getSkipActionWeiboCount() 
							|| weibo.getCommentNum() > SpiderConfig.getSkipActionWeiboCount()
							|| weibo.getForwardNum() > SpiderConfig.getSkipActionWeiboCount()
							|| count > SpiderConfig.getLatestActionWeiboCount()) break;
					
					//下载评论
					dateValue = df.format(new Date());
					String commentInfo = String.format("[%s]正在下载 %s[%s] 的微博 %s[%d/%d] 的评论信息", dateValue, ub.getNickName(), ub.getUid(), weibo.getMid(), count, weiboList.size());
					logger.info(commentInfo);
					//System.out.println(commentInfo);
					if(weibo.getCommentNum() > 0)
					{
						List<UserWeiboAction> commentList = wd.downloadUserWeiboAction(weibo, ActionType.COMMENT);
						if(!wd.isAccessDataBase)
							actionDao.insertActionList(commentList);
						commentList = null;
					}
					//目前只下载评论，其它忽略
//					if(true) continue;
					
					//下载转发
					//weiboDao.insertWeibo(weibo);
					dateValue = df.format(new Date());
					String forwardInfo = String.format("[%s]正在下载 %s[%s] 的微博 %s[%d/%d] 的转发信息", dateValue, ub.getNickName(), ub.getUid(), weibo.getMid(), count, weiboList.size());
					logger.info(forwardInfo);
					//System.out.println(forwardInfo);
					
					
					if(weibo.getForwardNum() > 0)
					{
						List<UserWeiboAction> forwardList = wd.downloadUserWeiboAction(weibo, ActionType.FORWARD);
						if(!wd.isAccessDataBase)
							actionDao.insertActionList(forwardList);
						forwardList = null;
					}
					//只下载转发
					//if(true) continue;
					
					
					
					dateValue = df.format(new Date());
					String likeInfo = String.format("[%s]正在下载 %s[%s] 的微博 %s[%d/%d] 的点赞信息", dateValue, ub.getNickName(), ub.getUid(), weibo.getMid(), count, weiboList.size());
					logger.info(likeInfo);
					//System.out.println(likeInfo);
					if(weibo.getLikeNum() > 0)
					{
						List<UserWeiboAction> likeList = wd.downloadUserWeiboAction(weibo, ActionType.LIKE);
						if(!wd.isAccessDataBase)
							actionDao.insertActionList(likeList);
						likeList = null;
					}
					
					/*
					 * 将已下载UID写入文件
					*/
					
//					count++;
					
				}
				
				//若未发生帐号异常将当前已下载UID弹出
				//downloadQueue.poll();
				if(!wd.checkAccount())
					wd = getUsefulDownloader(downloaderList);
				//List<String> fansList = wd.downloadUserFollowList(ub, RelationType.FANS);
				//downloadQueue.addAll(fansList);
			
			}
			catch (AccountForbiddonException e)
			{
				String oldAccount = wd.getLoginUser().getUserName();
				wd.finalise();
				//downloaderList.add(wd);
				wd = getUsefulDownloader(downloaderList);
				String newAccount = wd.getLoginUser().getUserName();
				System.out.println(String.format("帐号%s已经被封，切换为帐号%s,重新下载用户%s", oldAccount, newAccount, uid));
				e.printStackTrace();

				System.out.println("发生其它异常，即将开始下载下一个用户微博");
				//continue;
			}
			catch(Exception e)
			{
				String oldAccount = wd.getLoginUser().getUserName();
				wd.finalise();
				//downloaderList.add(wd);
				wd = getUsefulDownloader(downloaderList);
				String newAccount = wd.getLoginUser().getUserName();
				System.out.println(String.format("帐号%s已经被封，切换为帐号%s,重新下载用户%s", oldAccount, newAccount, uid));
				e.printStackTrace();

				System.out.println("发生其它异常，即将开始下载下一个用户微博");
				//continue;
			}
			
			
			
			
			
			
			
			
		}
	
		
	}
	
	public static WeiboDownloader getUsefulDownloader(Queue<WeiboDownloader> downloaderList)
	{
		WeiboDownloader wd = new WeiboDownloader();
		wd.setLogin(false);
		while(!wd.isLogin && downloaderList.size() > 0)
		{
			wd = downloaderList.poll();
			wd.init();
			wd.setAccessDataBase(true);
			if(!wd.checkAccount())
				wd.setLogin(false);
			String newAccount = wd.getLoginUser().getUserName();
			//downloadQueue.poll();
			System.out.println(String.format("老帐号已经被封，切换为帐号%s", newAccount));
		}
		if(wd != null)
			wd.setAccessDataBase(true);
		return wd;
		
		
	}
	
	
	
}
